package com.zmn.oms.dubbo.impl.zmn.fund;

import com.alibaba.fastjson.JSON;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import org.apache.dubbo.config.annotation.Service;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.response.ResponseUtil;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.dubbo.dto.zmn.refund.ApplyRefundDIO;
import com.zmn.oms.dubbo.dto.zmn.refund.RefundDetailDRO;
import com.zmn.oms.dubbo.dto.zmn.refund.RefundProgressDRO;
import com.zmn.oms.dubbo.interfaces.zmn.refund.RefundRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.dto.work.refund.RefundApplyDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.order.Order;
import com.zmn.oms.model.entity.refund.OrderWorkRefund;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.order.OrderService;
import com.zmn.oms.services.interfaces.refund.OrderWorkRefundService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.normal.business.interfaces.refund.RefundBService;
import com.zmn.pay.common.constant.PayConsts;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 类描述：退款实现类
 *
 * @author heciqi
 * @date 2019/08/09 14:54
 */
@Service(loadbalance = "roundrobin", timeout = 5000, retries = 2, version = DubboConsts.INTERFACE_VERSION)
public class RefundRemoteServiceImpl implements RefundRemoteService {

	private Logger logger = LoggerFactory.getLogger(RefundRemoteServiceImpl.class);

	@Autowired
	OrderWorkService orderWorkService;

	@Autowired
	OrderDetailService orderDetailService;
	@Autowired
	OrderService orderService;

	@Autowired
	RefundBService refundBService;
	@Autowired
	OrderWorkRefundService orderWorkRefundService;
	@Autowired
	OrderPayService orderPayService;

	/**
	 * 申请退款
	 *
	 * @param applyRefundDIO
	 * @return
	 */
	@Override
	public ResponseDTO applyRefund(ApplyRefundDIO applyRefundDIO) {
		logger.info("applyRefund-用户申请退款入参：{}", JSON.toJSONString(applyRefundDIO));
		Order order = orderService.findOrderByKey(applyRefundDIO.getOrderId());
		if (order == null) {
			return ResponseUtil.responseFail("订单不存在");
		}

		try {
			RefundApplyDTO refundApplyDTO = new RefundApplyDTO();
			refundApplyDTO.setOrderId(applyRefundDIO.getOrderId());
			refundApplyDTO.setWorkId(applyRefundDIO.getOrderId());
			refundApplyDTO.setApplyTime(DateUtil.getNow());
			refundApplyDTO.setReasonMap(applyRefundDIO.getReasonMap());
			refundApplyDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
			refundApplyDTO.setOperatorId(order.getUserId());
			OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(applyRefundDIO.getOrderId());
			refundApplyDTO.setOperator(StringUtils.defaultIfBlank(Optional.ofNullable(orderDetail).orElse(new OrderDetail()).getUserName(),"前端用户"));
			// 退款申请
			refundBService.applyRefund(refundApplyDTO);
		} catch (OmsBaseException e) {
			return ResponseUtil.responseFail(e.getMessage());
		} catch (Exception e) {
			logger.error("[{}]退款申请异常", applyRefundDIO.getOrderId(), e.getMessage(), e);
			return ResponseUtil.responseFail("申请退款失败");
		}

		return ResponseUtil.responseSuccess();
	}

	/**
	 * 退款明细
	 *
	 * @param orderId
	 * @return
	 */
	@Override
	public ResponseDTO<RefundDetailDRO>  refundDetail(Long orderId) {
		OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

		// 显示用户退款状态
		Integer refundStatus = OrderConsts.getUserRefundStatus(NumberUtil.isNotNullOrZero(orderWork.getRefundTargetWorkId()),orderWork.getRefundReviewStatus(), orderWork.getPayStatus());
		// 申请金额-所支付的金额
		Integer applyAmount = 0;
		if (Objects.equals(orderWork.getPrepayStatus(), PayConsts.PAY_STATUS_DONE) && orderWork.getPrepayAmount() != null) {
			applyAmount = applyAmount + orderWork.getPrepayAmount();
		}
		if (Objects.equals(orderWork.getDepositStatus(), PayConsts.PAY_STATUS_DONE) && orderWork.getDepositAmount() != null) {
			applyAmount = applyAmount + orderWork.getDepositAmount();
		}

		// 实际退款金额- 退款成功才显示
		Integer actualAmount = null;
		if (Objects.equals(orderWork.getPayStatus(), PayConsts.REFUND_STATUS_DONE)) {
			List<OrderPay> orderPays = orderPayService.listOrderPayByOrderId(orderId);
			actualAmount = orderPays.stream()
					.filter(e->Objects.equals(e.getTradeType(),PayConsts.PAY_TRADE_TYPE_REFUND))
					.mapToInt(e -> e.getAmount())
					.sum();
		}

		RefundDetailDRO refundDetailDRO = new RefundDetailDRO();
		refundDetailDRO.setOrderId(orderId);
		refundDetailDRO.setRefundStatus(refundStatus);
		refundDetailDRO.setApplyAmount(applyAmount);
		refundDetailDRO.setActualAmount(actualAmount);
		refundDetailDRO.setDiscountAmount(orderWork.getDiscountAmount());
		refundDetailDRO.setApplyTime(orderWork.getRefundApplyTime());
		refundDetailDRO.setRefundTime(orderWork.getRefundTime());
		refundDetailDRO.setRefundStatusName(PayConsts.getPayStatusName(refundStatus));

		// 退款进度
		if (refundStatus != null) {
			RefundProgressDRO step1 = new RefundProgressDRO(1, GlobalConsts.YES, orderWork.getRefundApplyTime());
			RefundProgressDRO step2 = new RefundProgressDRO(2, GlobalConsts.YES, orderWork.getRefundApplyTime());
			RefundProgressDRO step3 = new RefundProgressDRO(3, GlobalConsts.NO, orderWork.getRefundTime());
			// 已退款，最后个节点设置已处理
			if (Objects.equals(refundStatus, PayConsts.REFUND_STATUS_DONE)) {
				step3.setProcessFlag(GlobalConsts.YES);
			}
			refundDetailDRO.setRefundProgress(Lists.newArrayList(step1, step2,step3));
		}

		return ResponseUtil.responseSuccessData(refundDetailDRO);
	}
}
